
package view;

import controllers.CreateReport;
import controllers.FormReportValidator;
import controllers.LoginServiceControl;
import controllers.ServiceControl;
import entities.AmountRange;
import java.io.File;
import java.util.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import loginwebservice.Branch;

/**
 * @version 1.0
 * @date 13/04/2012
 * @author john
 */
public class StatsPane extends GridPane{
    
    private final double minTFWidth=200;
    private final double minCBWidth=200;
    private String initDateText="aaaa/mm/dd";
    
    private final ObservableList reportTypesList;
    private final ObservableList franchisesList;
    private final ObservableList branchOfficesList;
    private final ObservableList<AmountRange> amountRangesList;
    private ArrayList<Long> branchOfficesIdsList = new ArrayList<Long>();
    
    private HBox reportTypeHBox;
    private GridPane filterParamGrid;
    private Label reportTypeL;
    private Label startDateL;
    private Label endDateL;
    private Label franchiseL;
    private Label branchOfficeL;
    private Label amountRangeL;
    private TextField startDateTF;
    private TextField endDateTF;
    //TextField provicional para monto
    private TextField amountTF;
    private ChoiceBox reportTypeCB;
    private ChoiceBox franchiseCB;
    private ChoiceBox branchOfficeCB;
    //Comentado temporalmente para usar el TextField
    //private ChoiceBox amountRangeCB;
    private Button seeReportB;
    
    private Tooltip emptyStartDateT;
    private Tooltip emptyEndDateT;
    private Tooltip startDateT;
    private Tooltip endDateT;
    private Tooltip amountT;
    private Tooltip fileSelectedT;
    
    private ServiceControl serviceControl = new ServiceControl();
    private CreateReport createReportControl = new CreateReport();

    public StatsPane(final Stage primaryStage) {
        setId("stats-pane");
        setAlignment(Pos.CENTER);
        setPadding(new Insets(30, 30, 30, 30));
        setHgap(0);
        setVgap(20);
        reportTypesList=FXCollections.observableArrayList();
        franchisesList=FXCollections.observableArrayList();
        branchOfficesList=FXCollections.observableArrayList();
        amountRangesList=FXCollections.observableArrayList();
        initTooltips();
        initReportTypeHBox();
        initFilterParamGrid();
        seeReportB=new Button("Ver reporte");
        seeReportB.setOnAction(createReport(primaryStage,this));
        GridPane.setHalignment(seeReportB, HPos.RIGHT);
        add(reportTypeHBox,0,0);
        add(filterParamGrid,0,1);
        add(seeReportB,0,2);
    }
    
    /**
     * 
     */
    private void initTooltips(){
       emptyStartDateT=TooltipBuilder.create()
            .text("Se requiere una fecha de busqueda")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        emptyEndDateT=TooltipBuilder.create()
            .text("Se requiere una fecha de busqueda")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        startDateT=TooltipBuilder.create()
            .text("Fecha inválida")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        endDateT=TooltipBuilder.create()
            .text("Fecha inválida")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        amountT=TooltipBuilder.create()
            .text("Valor inválido para el monto")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
        fileSelectedT=TooltipBuilder.create()
            .text("¡Debe seleccionar un archivo!")
            .hideOnEscape(true)
            .autoHide(true)
            .build();
    }
    
    /**
     * 
     */
    private void fillReportTypesList(){
        List<String> list = serviceControl.getReportTypes();
        reportTypesList.setAll(list);
    }
    
    //<editor-fold defaultstate="collapsed" desc="fillAmountRangesList temporary disabled">
    /**
     * Comentado temporalmente
     */
    //    private void fillAmountRangesList(){
    //        amountRangesList.setAll(
    //            new AmountRange(0, 50000),
    //            new AmountRange(50000, 100000),
    //            new AmountRange(100000, 250000),
    //            new AmountRange(250000, 500000),
    //            new AmountRange(500000, 1000000),
    //            new AmountRange(1000000, 5000000),
    //            new AmountRange(5000000)
    //        );
    //    }
    //</editor-fold>
    
    /**
     * 
     */
    private void fillFranchisesList(){
        String allFranchises="Todas";
        // Esto es de prueba, debe llamar a un metodo control para recuperar todas las franquicias que esten registradas
        String franchisesTest1="VISA";
        String franchisesTest2="MasterCard";
        String franchisesTest3="American Express";
        franchisesList.setAll(
            allFranchises,
            new Separator(),
            franchisesTest1,
            franchisesTest2,
            franchisesTest3
        );
    }
    
    /**
     * 
     */
    private void fillBranchOfficesList(){
        branchOfficesList.add("Todas");
        branchOfficesList.add(new Separator());
        branchOfficesIdsList.add(0L);
        for (Iterator<Branch> it = LoginServiceControl.getBranchByStore(MainWindow.getActiveUser().getStore()).iterator(); it.hasNext();) {
            Branch e = (Branch) it.next();
            branchOfficesList.add(e.getBranchName());
            branchOfficesIdsList.add(e.getId());
        }
    }
    
    /**
     * 
     */
    private void initReportTypeHBox(){
        reportTypeHBox=new HBox(40);
        reportTypeHBox.setPadding(new Insets(20, 0, 0, 0));
        reportTypeL=new Label("Ver reporte de:");
        fillReportTypesList();
        reportTypeCB=new ChoiceBox<String>(reportTypesList);
        reportTypeCB.getSelectionModel().select(reportTypesList.get(0));
        reportTypeHBox.getChildren().setAll(reportTypeL,reportTypeCB);
    }
    
    /**
     * 
     */
    private void initFilterParamGrid(){
        fillFranchisesList();
        fillBranchOfficesList();
        //Comentado temporalmente
        //fillAmountRangesList();
        filterParamGrid=new GridPane();
        filterParamGrid.setPadding(new Insets(30));
        filterParamGrid.setHgap(25);
        filterParamGrid.setVgap(10);
        filterParamGrid.setId("filters-pane");
        startDateL=new Label("Fecha inicial:");
        endDateL=new Label("Fecha final:");
        franchiseL=new Label("Franquicia:");
        branchOfficeL=new Label("Sucursal:");
        amountRangeL=new Label("Monto:");
        startDateTF=new TextField(initDateText);
        endDateTF=new TextField(initDateText);
        //Inicialización para el TF de monto temporal
        amountTF = new TextField();
        //Comentado temporalmente
//        amountRangeCB=new ChoiceBox(amountRangesList);
//        amountRangeCB.getSelectionModel().select(amountRangesList.get(0));
        franchiseCB=new ChoiceBox(franchisesList);
        franchiseCB.getSelectionModel().select(franchisesList.get(0));
        branchOfficeCB=new ChoiceBox(branchOfficesList);
        branchOfficeCB.getSelectionModel().select(branchOfficesList.get(0));
        startDateTF.setMinWidth(minTFWidth);
        endDateTF.setMinWidth(minTFWidth);
        //SetMinWidth temporal
        amountTF.setMinWidth(minTFWidth);
        //Comentado temporalmente
        //amountRangeCB.setMinWidth(minCBWidth);
        franchiseCB.setMinWidth(minCBWidth);
        branchOfficeCB.setMinWidth(minCBWidth);
        filterParamGrid.add(startDateL,0,0);
        filterParamGrid.add(endDateL,0,1);
        filterParamGrid.add(branchOfficeL,0,2);
        filterParamGrid.add(startDateTF,1,0);
        filterParamGrid.add(endDateTF,1,1);
        filterParamGrid.add(branchOfficeCB,1,2);
        filterParamGrid.add(franchiseL,2,0);
        filterParamGrid.add(amountRangeL,2,2);
        filterParamGrid.add(franchiseCB,3,0);
        //Add temporal
        filterParamGrid.add(amountTF, 3, 2);
        //Comentado temporalmente
        //filterParamGrid.add(amountRangeCB,3,2);
    }
    
    private EventHandler<ActionEvent> createReport(final Stage primaryStage,final GridPane statsPane){
        return new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent arg0) {
                boolean validInfo=true;
                boolean checkStartDate=true;
                boolean checkEndDate=true;
                if (startDateTF.getText().toString().trim().equals(""))
                    checkStartDate=false;
                if (endDateTF.getText().toString().trim().equals(""))
                    checkEndDate=false;
                double amountValue = 0;
                String startDateValue = "0001/01/01";
                Calendar today=Calendar.getInstance();
                int month=(today.get(Calendar.MONTH)+1);
                int day=today.get(Calendar.DAY_OF_MONTH);
                String monthS=month<10?"0"+month:month+"";
                String dayS=day<10?"0"+day:day+"";
                String endDateValue=today.get(Calendar.YEAR)+"/"+monthS+"/"+dayS;
                if (!amountTF.getText().toString().trim().equals("")){
                    amountValue = FormReportValidator.validateAmount(amountTF.getText());
                    if (FormReportValidator.validateAmount(amountTF.getText()) == -1){
                        amountT.show(amountRangeL,
                            primaryStage.getX()+
                            amountRangeL.getLayoutX()+
                            20+
                            (primaryStage.getWidth()-filterParamGrid.getWidth())/2,
                            primaryStage.getY()+
                            amountRangeL.getLayoutY()+
                            filterParamGrid.getLayoutY()+
                            filterParamGrid.getPadding().getBottom()+
                            filterParamGrid.getPadding().getTop());
                        validInfo=false;
                    }
                }
                if(checkStartDate){
                    if (!FormReportValidator.syntacticValidationDate(startDateTF.getText())){
                        startDateT.show(startDateL,
                            primaryStage.getX()+
                            startDateL.getLayoutX()+
                            20+
                            (primaryStage.getWidth()-filterParamGrid.getWidth())/2,
                            primaryStage.getY()+
                            startDateL.getLayoutY()+
                            filterParamGrid.getLayoutY()+
                            filterParamGrid.getPadding().getBottom()+
                            filterParamGrid.getPadding().getTop());
                        validInfo=false;
                    }else{
                        startDateValue = startDateTF.getText();
                    }
                }
                if(checkEndDate){
                    if (!FormReportValidator.syntacticValidationDate(endDateTF.getText())){
                        endDateT.show(endDateL,
                            primaryStage.getX()+
                            endDateL.getLayoutX()+
                            20+
                            (primaryStage.getWidth()-filterParamGrid.getWidth())/2,
                            primaryStage.getY()+
                            endDateL.getLayoutY()+
                            filterParamGrid.getLayoutY()+
                            filterParamGrid.getPadding().getBottom()+
                            filterParamGrid.getPadding().getTop());
                        validInfo=false;
                    }else{
                        endDateValue = endDateTF.getText();
                    }
                }
                if(validInfo){
                    FileChooser fileSelector = new FileChooser();
                    File fileToSave = fileSelector.showSaveDialog(primaryStage);
                    if (fileToSave == null){
                        fileSelectedT.show(seeReportB,
                            primaryStage.getX()+
                            seeReportB.getLayoutX()-
                            170,
                            primaryStage.getY()+
                            seeReportB.getLayoutY()+
                            getVgap()*2);
                    }else {
                        boolean result = createReportControl.createReport(fileToSave, serviceControl.getTransactions(startDateValue, 
                            endDateValue, branchOfficesIdsList.get(branchOfficeCB.getSelectionModel().getSelectedIndex()), 
                            MainWindow.getActiveUser().getStore(), franchiseCB.getSelectionModel().getSelectedIndex(), 
                            reportTypeCB.getSelectionModel().getSelectedItem().toString(), amountValue));
                        if (result)
                            new ReportResultDialog(statsPane, primaryStage, "Reporte terminado", "El reporte se ha guardado.", true).show();
                        else
                            new ReportResultDialog(statsPane, primaryStage, "Error", "Ocurrió un error en la creación del reporte.", false).show();
                    }
                }
            }
        };
    }
    
    /**
     * 
     */
    protected void cleanFields(){
        startDateTF.setText(initDateText);
        endDateTF.setText(initDateText);
        amountTF.setText("");
        reportTypeCB.getSelectionModel().select(0);
        franchiseCB.getSelectionModel().select(0);
        branchOfficeCB.getSelectionModel().select(0);
    }
    
}
